package com.bsd.xxyp.rdlock.executor;

import com.bsd.xxyp.rdlock.annotation.RdLock;
import com.bsd.xxyp.rdlock.context.LockAnnotationDataExtractor;
import com.bsd.xxyp.rdlock.entity.LockInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;

import java.util.concurrent.TimeUnit;

/**
 * @author ：wangcheng
 * @date 2022/12/27
 **/
@Slf4j
public class ZkCuratorLockExecutor implements LockExecutor<InterProcessMutex>{

    private CuratorFramework curator;

    private static final String BASE_PATH = "/rdLock/zk/curator";

    public ZkCuratorLockExecutor(CuratorFramework curator) {
        this.curator = curator;
    }

    @Override
    public boolean tryAcquire(LockInfo<InterProcessMutex> lockInfo) {
        String nodePath = BASE_PATH.concat(lockInfo.getLockKey());
        InterProcessMutex lock = new InterProcessMutex(curator, nodePath);
        lockInfo.setLockClient(lock);
        try {
            return lock.acquire(lockInfo.getWaitTime(), TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            log.error("rdLock lock error: {}",e.getMessage());
        }
        return false;
    }

    @Override
    public boolean releaseLock(LockInfo<InterProcessMutex> lockInfo) {
        InterProcessMutex lock = lockInfo.getLockClient();
        if (lock.isAcquiredInThisProcess() && lockInfo.isLockSuccess()) {
            try {
                lock.release();
                return true;
            }catch (Exception e) {
                log.error("rdLock release lock exception: {}",e.getMessage());
                return false;
            }
        }else {
            log.info("rdLock: currentThread not hold lock so no need releaseLock ,lockKey: {} ",lockInfo.getLockKey());
            return false;
        }
    }
}
